package com.jkgj.skykingkong.tms.application;

import com.jkgj.skykingkong.tms.application.command.CreateUserCommand;
import com.jkgj.skykingkong.tms.application.command.UpdateUserCommand;
import com.jkgj.skykingkong.tms.domain.model.rbac.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author Xuegui Yuan
 */
@Service
public class RbacService {
  @Autowired
  private UserRepository userRepository;

  @Autowired
  private RoleRepository roleRepository;

  @Autowired
  private PermissionRepository permissionRepository;

  @Transactional
  public void createUser(CreateUserCommand createUserCommand) {
    User user = new User(createUserCommand.getUsername(),
        createUserCommand.getPassword(),
        createUserCommand.getMobile(),
        createUserCommand.getEmail(),
        createUserCommand.getName());
    userRepository.save(user);
  }

  @Transactional
  public void updateUser(UpdateUserCommand updateUserCommand) {
    User user = userRepository.findOne(updateUserCommand.getId());
    if (StringUtils.isNoneBlank(updateUserCommand.getPassword())) {
      user.changePassword(updateUserCommand.getPassword());
    }
    user.setMobile(updateUserCommand.getMobile());
    user.setEmail(updateUserCommand.getEmail());
    user.setName(updateUserCommand.getName());
    userRepository.update(user);
  }

  @Transactional
  public void deleteUser(Long userId) {
    userRepository.delete(userId);
  }

  @Transactional
  public void createOrUpdateRole(Role role) {
    roleRepository.save(role);
  }

  @Transactional
  public void deleteRole(Long roleId) {
    roleRepository.delete(roleId);
  }

  @Transactional
  public void createOrUpdatePermission(Permission permission) {
    permissionRepository.save(permission);
  }

  @Transactional
  public void deletePermission(Long permissionId) {
    permissionRepository.delete(permissionId);
  }

  @Transactional
  public void grantRoles(Long userId, List<String> roleCodes) {
    User user = userRepository.findOne(userId);
    List<Role> roles = roleRepository.query().where()
        .in("code", roleCodes).findList();
    user.grantRoles(roles);
    userRepository.save(user);
  }

  @Transactional
  public void grantPermissions(Long roleId, List<String> permissionCodes) {
    Role role = roleRepository.findOne(roleId);
    List<Permission> permissions = permissionRepository.query().where()
        .in("code", permissionCodes).findList();
    role.grantPermissions(permissions);
    roleRepository.save(role);
  }

  @Transactional
  public void enableUser(Long userId) {
    User user = userRepository.findOne(userId);
    user.enable();
    userRepository.save(user);
  }

  @Transactional
  public void disableUser(Long userId) {
    User user = userRepository.findOne(userId);
    user.disable();
    userRepository.save(user);
  }

}
